<?php
class Sentiments extends Dao
{
	private static $_instance = null;
	protected $_db = null, $_cache = null;
	
	protected function __construct()
	{
		parent::__construct();
	}
	
	public static function getInstance() 
    {
        if (null === self::$_instance) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }
	
	public function hasSentiment($postId, $userId)
	{
		$strSql = " SELECT 1
					FROM tbl_cms_post_sentiment
					WHERE post_id=:pid AND user_id =:uid";
		$cmd = $this->_db->createCommand($strSql);
		$cmd->bindParam(":pid",$postId,PDO::PARAM_STR);
		$cmd->bindParam(":uid",$userId,PDO::PARAM_STR);
		return $found = $cmd->queryScalar();	
	}
	
	//If postId is null --> update all posts
	public function purgePostLike($postId = null){
		try{
			if($postId === null){
				
			} else {
				
			}
		} catch(Exception $ex){
			throw new Exception($ex->getMessage());
		}	
	}
	
	//If postId is null --> update all posts
	public function purgePostRate($postId = null){
		try{
			if($postId === null){
				$strSql = " UPDATE tbl_cms_posts p
							INNER JOIN (
								SELECT post_id, AVG(rate) as avg_rate FROM tbl_cms_post_sentiment GROUP BY post_id
							) AS r ON p.post_id = r.post_id
							SET post_average_rating = r.avg_rate; ";
				$cmd = $this->_db->createCommand($strSql);
				return $cmd->execute();
			} else {
				$strSql = " UPDATE tbl_cms_posts 
							SET post_average_rating = (SELECT AVG(rate) FROM tbl_cms_post_sentiment WHERE post_id = :pid GROUP BY post_id) WHERE post_id = :pid; ";
				$cmd = $this->_db->createCommand($strSql);
				$cmd->bindParam(":pid",$postId,PDO::PARAM_STR);
				return $cmd->execute();
			}
		} catch(Exception $ex){
			throw new Exception($ex->getMessage());
		}	
	}
	
	//like a post, vote a post
	public function likePost($postId, $userId)
	{
		if(empty($postId) || empty($userId)) throw Exception('Invalid Input');
		$args = array(
			'post_id'=>$postId, 
			'user_id'=>$userId, 
			'like'=>1,
			'like_date'=>new CDbExpression('NOW()')
		);
		try{
			$found = $this->hasSentiment($postId, $userId);
			if($found){
				//found nhưng do trước đó đã unlinke => field = null
				$result = 0;
				//đã like -> do nothing
				//update
				//$result =  $cmd->update('tbl_cms_post_sentiment',$args, 'post_id=:pid AND user_id=:uid', array(':pid'=>$postId, ':uid'=>$userId));
			}
			else{
				//insert
				$result = $this->_db->createCommand()->insert('tbl_cms_post_sentiment', $args);
			}
			//increase like count
			if($result == 1){
				$strSql = "UPDATE tbl_cms_posts SET post_likes_count = post_likes_count + 1 WHERE post_id = :pid";
				$cmd = $this->_db->createCommand($strSql);
				$cmd->bindParam(":pid",$postId,PDO::PARAM_STR);
				return $cmd->execute();
			}
			//TODO: khi delete user phải tính lại con số total này (trigger)
			return 0;
		} catch(Exception $ex){
			throw new Exception($ex->getMessage());
		}
	}
	
	public function ratePost($postId, $userId, $score, $allowUpdate = true)
	{
		if(empty($postId) || empty($userId)) throw Exception('Invalid Input');
		$args = array(
			'post_id'=>$postId, 
			'user_id'=>$userId, 
			'rate'=>$score,
			'rate_date'=>new CDbExpression('NOW()')
		);
		try{
			$found = $this->hasSentiment($postId, $userId);
			if($found){
				$result = 0;
				//allow update?
				if($allowUpdate){
					$result = $this->_db->createCommand()->update('tbl_cms_post_sentiment', $args, 'post_id = :pid AND user_id = :uid', array(':pid'=>$postId, ':uid'=>$userId));
				}
			}
			else{
				//insert
				$result = $this->_db->createCommand()->insert('tbl_cms_post_sentiment', $args);
			}
			//re-calculate average rating score
			//TODO: khi delete user phải tính lại con số trung bình này (trigger)
			if($result == 1){
				$this->purgePostRate($postId);
				/*clear cache*/
				$this->clearMasterCache(CACHE_POST_MASTER);
			}
			return $result;
		} catch(Exception $ex){
			throw new Exception($ex->getMessage());
		}
	}
}